//版权所有--董清潭
package com.tjtt.common.utils;

import java.io.*;
import java.nio.*;
import java.nio.channels.FileChannel;

public class FileDES{
	private static final boolean enc=true;    //加密
	private static final boolean dec=false;	  //解密
	
	private String srcFileName;
	private String destFileName;
	private String inKey;
	private boolean actionType;
	private File srcFile;
	private File destFile;	
	private Des des;
	
	private void analyzePath(){
		String dirName;
		int pos=srcFileName.lastIndexOf("/");
		dirName=srcFileName.substring(0,pos);
		File dir=new File(dirName);
		if (!dir.exists()){
			System.err.println(dirName+" is not exist");
			System.exit(1);
		}else if(!dir.isDirectory()){
			System.err.println(dirName+" is not a directory");
			System.exit(1);
		}
		
		pos=destFileName.lastIndexOf("/");
		dirName=destFileName.substring(0,pos);
		dir=new File(dirName);
		if (!dir.exists()){
			if(!dir.mkdirs()){
				System.out.println ("can not creat directory:"+dirName);
				System.exit(1);
			}
		}else if(!dir.isDirectory()){
			System.err.println(dirName+" is not a directory");
			System.exit(1);
		}
	}
	
	private static int replenish(FileChannel channel,ByteBuffer buf) throws IOException{
		long byteLeft=channel.size()-channel.position();
		if(byteLeft==0L)
			return -1;
		buf.position(0);
		buf.limit(buf.position()+(byteLeft<8 ? (int)byteLeft :8));
		return channel.read(buf);
	}
	
	private void file_operate(boolean flag){
		des=new Des(inKey);
		FileOutputStream outputFile=null;
		try {
			outputFile=new FileOutputStream(srcFile,true);
	    }catch (java.io.FileNotFoundException e) {
	    	e.printStackTrace(System.err);
	    }
	    FileChannel outChannel=outputFile.getChannel();
	    
	    try{
		    if(outChannel.size()%2!=0){
				ByteBuffer bufTemp=ByteBuffer.allocate(1);
				bufTemp.put((byte)32);
				bufTemp.flip();			
				outChannel.position(outChannel.size());
				outChannel.write(bufTemp);
		    	bufTemp.clear();		
			}
		}catch(Exception ex){
			ex.printStackTrace(System.err);
			System.exit(1);
		}
		FileInputStream inFile=null;
		try{
			inFile=new FileInputStream(srcFile);
		}catch(java.io.FileNotFoundException e){
			e.printStackTrace(System.err);
			//System.exit(1);
		}
		outputFile=null;
		try {
			outputFile=new FileOutputStream(destFile,true);
	    }catch (java.io.FileNotFoundException e) {
	    	e.printStackTrace(System.err);
	    }
	    
	    FileChannel inChannel=inFile.getChannel();
		outChannel=outputFile.getChannel();
		
		
		ByteBuffer inBuf=ByteBuffer.allocate(2048);
		ByteBuffer outBuf=ByteBuffer.allocate(2048);
		
		try{
			String srcStr;
			String destStr;
			while(true){
			
				if (replenish(inChannel,inBuf)==-1) break;
				srcStr=((ByteBuffer)(inBuf.flip())).asCharBuffer().toString();
				inBuf.clear();
				if (flag)
					destStr=des.enc(srcStr,srcStr.length());
				else
					destStr=des.dec(srcStr,srcStr.length());
			    outBuf.clear();
			    if (destStr.length()==4){
			    	for (int i = 0; i<4; i++) {
	    				outBuf.putChar(destStr.charAt(i));
	    			}
			    	outBuf.flip();
			    }else{
			    	outBuf.position(0);
			    	outBuf.limit(2*destStr.length());
			    	for (int i = 0; i<destStr.length(); i++) {
	    				outBuf.putChar(destStr.charAt(i));
	    			}
			    	outBuf.flip();
			    }
			    
			    try {
	    			outChannel.write(outBuf);
	    			outBuf.clear();
	    		}catch (java.io.IOException ex) {
	    			ex.printStackTrace(System.err);
	    		}
			}
			System.out.println (inChannel.size());
	    	System.out.println (outChannel.size());
			System.out.println ("EoF reached.");
			inFile.close();
			outputFile.close();
		}catch(java.io.IOException e){
			e.printStackTrace(System.err);
			System.exit(1);
		}	
	}

	public FileDES(String srcFileName,String destFileName,String inKey,boolean actionType){
		this.srcFileName=srcFileName;
		this.destFileName=destFileName;		
		this.actionType=actionType;
		analyzePath();
		srcFile=new File(srcFileName);
		destFile=new File(destFileName);		
		this.inKey=inKey;
		if (actionType==enc)
			file_operate(enc);
		else
			file_operate(dec);
	}
	
	
	public static void main(String[] args){
		String file1="c://TDDOWNLOAD.rar";
		System.out.println(file1);
		String file2="c://1";
		String file3="c://TDDOWNLOAD2.rar";
		String passWord="11111111";
		FileDES fileDes=new FileDES(file1,file2,passWord,true);
		FileDES fileDes1=new FileDES(file2,file3,passWord,false);
	}
	
}